﻿using Engine;
using Game;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using XmlUtilities;
using static Game.VersionsManager;

namespace StyleMap
{
    /// <summary>
    /// 负责加载游戏中的样式Mod（.stylescmod）文件的类。
    /// 继承自ModLoader，用于在游戏启动时注册并加载自定义Mod资源。
    /// </summary>
    public class GameInfoLoader : ModLoader
    {
        /// <summary>
        /// 初始化Mod加载器，向ModsManager注册"OnLoadingStart"钩子。
        /// </summary>
        public override void __ModInitialize()
        {
            ModsManager.RegisterHook("OnLoadingStart", this);
        }

        /// <summary>
        /// 在游戏加载开始时调用，添加一个委托以加载所有样式Mod。
        /// </summary>
        /// <param name="actions">游戏加载过程中执行的动作列表。</param>
        public override void OnLoadingStart(List<System.Action> actions)
        {
            actions.Add(delegate
            {
                LoadAllStylescmods(ModsPath);
            });
        }

        /// <summary>
        /// 存储待加载的所有Mod实体的静态列表。
        /// </summary>
        public static List<ModEntity> ToLoadFModListAll = new List<ModEntity>();

        /// <summary>
        /// 获取Mod文件所在的路径。
        /// 根据平台不同返回不同的路径，Android平台返回特定路径，其他平台返回默认路径。
        /// </summary>
        public static string ModsPath
        {
            get
            {
                try
                {
                    if (IsAndroidPlatform())
                    {
                        return "android:/Survivalcraft2.3/Mods";
                    }
                }
                catch
                {
                }
                return "app:/Mods";
            }
        }

        /// <summary>
        /// 判断当前运行环境是否为Android平台。
        /// 通过检查是否存在Android相关类型或环境变量来判断。
        /// </summary>
        /// <returns>如果是Android平台返回true，否则返回false。</returns>
        private static bool IsAndroidPlatform()
        {
            try
            {
                var androidActivity = Type.GetType("Android.App.Activity, Mono.Android");
                if (androidActivity != null)
                {
                    return true;
                }

                if (Environment.GetEnvironmentVariable("ANDROID_DATA") != null)
                {
                    return true;
                }
            }
            catch
            {
            }
            return false;
        }

        /// <summary>
        /// 遍历指定路径下的所有文件和子目录，加载所有扩展名为.stylescmod的Mod文件。
        /// 支持递归加载子目录中的Mod文件。
        /// </summary>
        /// <param name="path">要扫描并加载Mod文件的根路径。</param>
        public static void LoadAllStylescmods(string path)
        {
            // 遍历当前目录下的所有文件
            foreach (string item in Storage.ListFileNames(path))
            {
                string ms = Storage.GetExtension(item);
                string ks = Storage.CombinePaths(path, item);

                using (Stream stream = Storage.OpenFile(ks, OpenFileMode.Read))
                {
                    try
                    {
                        if (ms == ".stylescmod")
                        {
                            // 解密并打开Mod文件流
                            Stream keepOpenStream = ModsManageContentScreen.GetDecipherStream(stream);
                            var modEntity = new ModEntity(ZipArchive.Open(keepOpenStream, true));

                            // 检查Mod是否包含必要信息
                            if (modEntity.modInfo == null)
                            {
                                Log.Warning($"跳过无效的mod文件: {ks} (缺少modinfo)");
                                return;
                            }

                            try
                            {
                                // 加载语言文件
                                try
                                {
                                    modEntity.LoadLauguage();
                                }
                                catch (Exception ex)
                                {
                                    Log.Warning($"加载语言文件失败: {ex.Message}");
                                }

                                // 加载CSV数据文件（如方块数据）
                                try
                                {
                                    bool hasCsvFiles = false;
                                    modEntity.GetFiles(".csv", (filename, fileStream) => {
                                        hasCsvFiles = true;
                                    });

                                    if (hasCsvFiles)
                                    {
                                        modEntity.LoadBlocksData();
                                        Log.Information($"[{modEntity.modInfo.Name}] 已处理方块数据文件");
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Log.Warning($"[{modEntity.modInfo.Name}] 加载方块数据失败: {ex.Message}");
                                }

                                // 加载CR合成配方文件
                                try
                                {
                                    bool hasCrFiles = false;
                                    modEntity.GetFiles(".cr", (filename, fileStream) => {
                                        hasCrFiles = true;
                                    });

                                    if (hasCrFiles)
                                    {
                                        XElement craftingRecipes = new XElement("CraftingRecipes");
                                        modEntity.LoadCr(ref craftingRecipes);
                                        Log.Information($"[{modEntity.modInfo.Name}] 已处理合成配方文件");
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Log.Warning($"[{modEntity.modInfo.Name}] 加载合成配方失败: {ex.Message}");
                                }

                                // 加载XDB数据库文件
                                try
                                {
                                    bool hasXdbFiles = false;
                                    modEntity.GetFiles(".xdb", (filename, fileStream) => {
                                        hasXdbFiles = true;
                                    });

                                    if (hasXdbFiles)
                                    {
                                        XElement database = new XElement("Database");
                                        modEntity.LoadXdb(ref database);
                                        Log.Information($"[{modEntity.modInfo.Name}] 已处理数据库文件");
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Log.Warning($"[{modEntity.modInfo.Name}] 加载数据库失败: {ex.Message}");
                                }

                                // 加载CLO服装数据文件
                                try
                                {
                                    bool hasCloFiles = false;
                                    modEntity.GetFiles(".clo", (filename, fileStream) => {
                                        hasCloFiles = true;
                                    });

                                    if (hasCloFiles)
                                    {
                                        ClothingBlock clothingBlock = new ClothingBlock();
                                        XElement clothing = new XElement("Clothing");
                                        modEntity.LoadClo(clothingBlock, ref clothing);
                                        Log.Information($"[{modEntity.modInfo.Name}] 已处理服装数据文件");
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Log.Warning($"[{modEntity.modInfo.Name}] 加载服装数据失败: {ex.Message}");
                                }

                                // 加载JS脚本文件
                                try
                                {
                                    bool hasJsFiles = false;
                                    modEntity.GetFiles(".js", (filename, fileStream) => {
                                        hasJsFiles = true;
                                    });

                                    if (hasJsFiles)
                                    {
                                        modEntity.LoadJs();
                                        Log.Information($"[{modEntity.modInfo.Name}] 已处理JavaScript文件");
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Log.Warning($"[{modEntity.modInfo.Name}] 加载JS脚本失败: {ex.Message}");
                                }

                                // 加载DLL程序集文件
                                try
                                {
                                    bool hasDllFiles = false;
                                    modEntity.GetFiles(".dll", (filename, fileStream) => {
                                        if (!filename.StartsWith("Assets/"))
                                        {
                                            hasDllFiles = true;
                                        }
                                    });

                                    if (hasDllFiles)
                                    {
                                        Assembly[] assemblies = modEntity.GetAssemblies();
                                        foreach (Assembly assembly in assemblies)
                                        {
                                            modEntity.HandleAssembly(assembly);
                                        }
                                        Log.Information($"[{modEntity.modInfo.Name}] 已处理程序集文件");
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Log.Warning($"[{modEntity.modInfo.Name}] 加载程序集失败: {ex.Message}");
                                }

                                Log.Information($"完成处理mod: {modEntity.modInfo.Name}");
                            }
                            catch (Exception ex)
                            {
                                Log.Error($"处理mod文件时出错: {ex.Message}");
                            }

                            ModsManager.ModListAll.Add(modEntity);
                            LoadingScreen.Info("已加载开源小地图附属包: " + modEntity.modInfo.Name);
                        }
                    }
                    catch (Exception e)
                    {
                        ModsManager.AddException(e);
                        stream.Close();
                    }
                }
            }

            // 递归遍历子目录
            foreach (string dir in Storage.ListDirectoryNames(path))
            {
                LoadAllStylescmods(Storage.CombinePaths(path, dir));
            }
        }
    }
}